package tk.leafotto.sign2.activity;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.animation.AlphaAnimation;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.TimeUnit;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import tk.leafotto.sign2.R;
import tk.leafotto.sign2.bean.ResBaseModel;
import tk.leafotto.sign2.bean.VersionModel;
import tk.leafotto.sign2.utils.ConstantValue;
import tk.leafotto.sign2.utils.NetStatUtil;
import tk.leafotto.sign2.utils.SpUtil;
import tk.leafotto.sign2.utils.ToastUtil;
import tk.leafotto.sign2.utils.net.CheckUpdate;
import tk.leafotto.sign2.utils.net.CheckUpdateUseAdapter;
import tk.leafotto.sign2.utils.net.ComApi;
import tk.leafotto.sign2.utils.net.DownloadInterface;

public class WelcomeActivity extends Activity {

    private static final String TAG = "WelcomeActivity";
    private RelativeLayout rl_welcome;
    private String mVersionDes;
    private TextView tv_ver;
    private String mUpdateUrl;
    private File apkFile;
    private boolean writtenToDisk;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_welcome);
        initUI();
        initData();
    }

    private void initUI() {
        rl_welcome = (RelativeLayout) findViewById(R.id.ll_welcome);
        //渐入动画
        initAnimation();
        tv_ver = (TextView)findViewById(R.id.tv_ver);

    }

    private void initData(){
        //点击跳过封面
        rl_welcome.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                enterHome();
                return true;
            }
        });
        tv_ver.setText("版本：" + getVersionName());
        if(SpUtil.getBoolean(this, ConstantValue.OPEN_UPDATE,false)){
            checkVersion();
        }else {
            //RxJava Code
            Observable.timer(4,TimeUnit.SECONDS).subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    enterHome();
                }
            });
        }
    }

    private void checkVersion() {
        final long startTime = System.currentTimeMillis();
        OkHttpClient okhttp = new OkHttpClient.Builder()
                .connectTimeout(1, TimeUnit.SECONDS)
                .writeTimeout(5, TimeUnit.SECONDS)
                .readTimeout(1, TimeUnit.SECONDS)
                .addInterceptor(new HttpLoggingInterceptor())//日志
                .build();
        final Retrofit retrofitUpdate = new Retrofit.Builder()
                .baseUrl("http://192.168.1.87")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(okhttp)
                .build();
        CheckUpdateUseAdapter checkUpdateUseAdapter = retrofitUpdate.create(CheckUpdateUseAdapter.class);
        checkUpdateUseAdapter.checkUpdate()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<ResBaseModel<VersionModel>>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(Long.MAX_VALUE);
                        Log.e(TAG,"onSubscribe");
                        System.out.println("onSubscribe");
                    }

                    @Override
                    public void onNext(ResBaseModel<VersionModel> versionModelResBaseModel) {
                        Log.e(TAG,"onNext");
                        System.out.println("onNext");
                        //请求成功
                        int newVersionCode = versionModelResBaseModel.getData().getVersionCode();
                        if(newVersionCode > getVerisonCode() && getVerisonCode() > 0){
                            mVersionDes = versionModelResBaseModel.getData().getUpdateContent();
                            mUpdateUrl = versionModelResBaseModel.getData().getUrl();
                            showUpdateDailog();
                        }
                    }

                    @Override
                    public void onError(Throwable t) {
                        Log.e(TAG,"onError");
                        System.out.println("onError");
                        //请求失败
                        ToastUtil.show(WelcomeActivity.this, "获取更新时网络异常");
                        long endTime = System.currentTimeMillis();
                        long disTime = 4000-(endTime-startTime);
                        Log.e("*******************",disTime + "");
                        Observable.timer(disTime,TimeUnit.MILLISECONDS).subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                enterHome();
                            }
                        });
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG,"onComplete");
                        System.out.println("onComplete");
                    }
                });
    }

    //当世界上没有了Retrofit2-RxJava2-Adapter，我们只能这样做。
/*    private void checkVersion() {
        final long startTime = System.currentTimeMillis();
        OkHttpClient okhttp = new OkHttpClient.Builder()
                .connectTimeout(1, TimeUnit.SECONDS)
                .writeTimeout(5, TimeUnit.SECONDS)
                .readTimeout(1, TimeUnit.SECONDS)
                .addInterceptor(new HttpLoggingInterceptor())//日志
                .build();
        final Retrofit retrofitUpdate = new Retrofit.Builder()
                .baseUrl("http://192.168.1.87")
                .addConverterFactory(GsonConverterFactory.create())
                .client(okhttp)
                .build();
        Flowable.create(new FlowableOnSubscribe<ResBaseModel<VersionModel>>() {
            @Override
            public void subscribe(final FlowableEmitter<ResBaseModel<VersionModel>> e) throws Exception {
                CheckUpdate checkUpdate = retrofitUpdate.create(CheckUpdate.class);
                Call<ResBaseModel<VersionModel>> resBaseModelCall = checkUpdate.checkUpdate();
                resBaseModelCall.enqueue(new Callback<ResBaseModel<VersionModel>>() {
                    @Override
                    public void onResponse(Call<ResBaseModel<VersionModel>> call, Response<ResBaseModel<VersionModel>> response) {
                        if(!e.isCancelled()){
                            e.onNext(response.body());
                        }
                        call.cancel();
                        e.onComplete();
                    }

                    @Override
                    public void onFailure(Call<ResBaseModel<VersionModel>> call, Throwable t) {
                        if(!e.isCancelled()){
                            e.onError(t);
                        }
                        call.cancel();
                        e.onComplete();
                    }
                });
            }
        }, BackpressureStrategy.BUFFER)
                .doOnNext(new Consumer<ResBaseModel<VersionModel>>() {
                    @Override
                    public void accept(ResBaseModel<VersionModel> versionModelResBaseModel) throws Exception {
                        if(versionModelResBaseModel.isSuccess()){
                            //请求成功
                            int newVersionCode = versionModelResBaseModel.getData().getVersionCode();
                            if(newVersionCode > getVerisonCode() && getVerisonCode() > 0){
                                mVersionDes = versionModelResBaseModel.getData().getUpdateContent();
                                mUpdateUrl = versionModelResBaseModel.getData().getUrl();
                                showUpdateDailog();
                            }
                        }else {
                            ToastUtil.show(WelcomeActivity.this, "获取更新数据异常");
                            long endTime = System.currentTimeMillis();
                            long disTime = 4000-(endTime-startTime);
                            Log.e("*******************",disTime + "");
                            Observable.timer(disTime,TimeUnit.MILLISECONDS).subscribe(new Consumer<Long>() {
                                @Override
                                public void accept(Long aLong) throws Exception {
                                    enterHome();
                                }
                            });
                        }
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnError(new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        //捕获异常
                        throwable.printStackTrace();
                        //请求失败
                        ToastUtil.show(WelcomeActivity.this, "获取更新时网络异常");
                        long endTime = System.currentTimeMillis();
                        long disTime = 4000-(endTime-startTime);
                        Log.e("*******************",disTime + "");
                        Observable.timer(disTime,TimeUnit.MILLISECONDS).subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                enterHome();
                            }
                        });
                    }
                })
                .onErrorResumeNext(Flowable.<ResBaseModel<VersionModel>>empty())
                .subscribe();
    }*/



    /**
     * 获取应用版本名称的方法
     * @return 应用版本名称 返回null代表出现异常
     */
    private String getVersionName() {
        //获取包管理者
        PackageManager pm = getPackageManager();
        try {
            PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
            String versionName = packageInfo.versionName;
            return versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    private int getVerisonCode(){
        PackageManager pm = getPackageManager();
        try {
            PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
            return packageInfo.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return -1;
    }

    private void initAnimation() {
        AlphaAnimation alphaAnimation = new AlphaAnimation(0,1);
        alphaAnimation.setDuration(3000);
        rl_welcome.startAnimation(alphaAnimation);
    }

    protected void showUpdateDailog() {
        //对话框依赖于Activity存在，参数必须是this
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
//        builder.setIcon(R.mipmap.ic_launcher);
        builder.setTitle("发现新版本");
        builder.setMessage(mVersionDes);
        builder.setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                NetStatUtil netStatUtil = new NetStatUtil();
                if(netStatUtil.isWifiConnected(getApplicationContext())){
                    //下载apk
                    downloadApk();
                }else {
                    showNoWifiUpdate();
                }
            }
        });
        builder.setNegativeButton("暂不更新", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //取消对话框，进入主界面
                enterHome();
            }
        });
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                enterHome();
                dialog.dismiss();
            }
        });
        builder.show();
    }

    protected void showNoWifiUpdate() {
        //对话框依赖于Activity存在，参数必须是this
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
//        builder.setIcon(R.mipmap.ic_launcher);
        builder.setTitle("网络提醒");
        builder.setMessage("下载最新安装包将消耗5MB流量，建议在wifi环境中下载。");
        builder.setPositiveButton("土豪继续下载", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //下载apk
                downloadApk();
            }
        });
        builder.setNegativeButton("暂时不下载", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //取消对话框，进入主界面
                enterHome();
            }
        });
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                enterHome();
                dialog.dismiss();
            }
        });
        builder.show();
    }

    private void downloadApk() {
        //判断SD卡是否挂载
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            //获取SD路径
            String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "sign2.apk";
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(10000L,TimeUnit.MILLISECONDS)       //设置连接超时
                    .readTimeout(10000L,TimeUnit.MILLISECONDS)          //设置读取超时
                    .writeTimeout(10000L,TimeUnit.MILLISECONDS)         //设置写入超时
                    .cache(new Cache(getCacheDir(),10 * 1024 * 1024))   //设置缓存目录和10M缓存
                    .addInterceptor(interceptor)    //添加日志拦截器（该方法也可以设置公共参数，头信息）
                    .build();
            final Retrofit retrofitDownload = new Retrofit.Builder()
                    .baseUrl(mUpdateUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(client)
                    .build();

            DownloadInterface downloadInterface = retrofitDownload.create(DownloadInterface.class);
            downloadInterface.download()
                    .subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io())
                    .doOnNext(new Consumer<ResponseBody>() {
                        @Override
                        public void accept(ResponseBody responseBody) throws Exception {
                            Log.d(TAG,"连接成功，文件存在！");
                            Log.e("ThreadNameIs:",Thread.currentThread().getName());
                            writtenToDisk = writeResponseBodyToDisk(responseBody);
                            Log.d(TAG, "file download was a success? " + writtenToDisk);
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnNext(new Consumer<ResponseBody>() {
                        @Override
                        public void accept(ResponseBody responseBody) throws Exception {
                            ToastUtil.show(getApplicationContext(),"下载完成，开始安装！");
                            enterHome();
                            installApk(apkFile);
                        }
                    })
                    .doOnError(new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            if(writtenToDisk){
                                Log.e("ThreadNameIs:",Thread.currentThread().getName());
                                Log.d(TAG, "server contact failed");
                                ToastUtil.show(getApplicationContext(),"升级服务器连接失败，请稍后再试！");
                            }else{
                                ToastUtil.show(getApplicationContext(),"升级包下载失败，请稍后再试！");
                            }
                            enterHome();
                        }
                    })
                    .subscribe();
        }
    }

    private boolean writeResponseBodyToDisk(ResponseBody body) {
        try {
            // todo change the file location/name according to your needs
            apkFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "sign2.apk");
            InputStream inputStream = null;
            OutputStream outputStream = null;
            try {
                byte[] fileReader = new byte[4096];
                long fileSize = body.contentLength();
                long fileSizeDownloaded = 0;
                inputStream = body.byteStream();
                outputStream = new FileOutputStream(apkFile);
                while (true) {
                    int read = inputStream.read(fileReader);
                    if (read == -1) {
                        break;
                    }
                    outputStream.write(fileReader, 0, read);
                    fileSizeDownloaded += read;
                    Log.d(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
                }
                outputStream.flush();
                return true;
            } catch (IOException e) {
                return false;
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            }
        } catch (IOException e) {
            return false;
        }
    }

    /**
     * 安装apk
     * @param file
     */
    protected void installApk(File file) {
        Intent intent = new Intent("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        startActivityForResult(intent, 0);
    }

    private void enterHome() {
        startActivity(new Intent(getApplicationContext(),MainActivity.class));
        finish();
    }
}
